<?php
namespace wow\controller;

use \gnomephp\message\Message;

use \wow\modelauth;
use \wow\model\dbcon as dbs;
use \gnomephp\doctrine\Doctrine;
use \wow\modelauth as mauth;

class Auth extends \gnomephp\security\Security implements \gnomephp\security\Secure{

	/**
	 *
	 * @var wow\modelauth\Account
	 */
	private $user = null;

	public function __construct(){
		parent::__construct();

		dbs\AuthDB::load();
		$this->view->assignGlobal('realms', mauth\Realmlist::getAllRealms());
		
		$this->view->assignGlobal('APP_VERSION', BaseController::APP_VERSION);
		
		$this->view->lang->load('account');
	}

	public function hasAccessTo($method, $session){
		if (is_object($session) && $session->getUsername()){
			dbs\AuthDB::load();

			$this->user = $this->user = mauth\Account::getUserByUsername($session->getUsername());
			$this->view->assignGlobal('user', $this->user);
			$this->view->assignGlobal('showAdminLink', $this->hasPermissionTo('admin_panel'));
			
		}else{
			$this->view->assignGlobal('user', null);
		}
		
		return true;
	}


	public function hasPermissionTo($config){

		$config = \gnomephp\Configuration::get('permission', $config);

		if ($this->user){

			$level = $this->user->getGmLevel();
			if ($level){
				if (is_array($config) && in_array($level, $config)){
					return true;
				}elseif($level >= $config){
					return true;
				}
			}
		}else{
			if (is_array($config) && in_array(0, $config)){
				return true;
			}elseif($config == 0)return true;
		}
		return false;
	}


	protected function authenticate($username, $password){
		$result = modelauth\Account::authenticate((string)$username, (string)$password);
		return (bool)$result;
	}

	public function manage(){
		if (!$this->user){
			$this->redirect($this->view->url->linkTo('Application','index'));
		}

		$user = $this->user;
		$controller = $this;

		$form = $this->view->createForm('manage', $this->view->url->linkTo('Auth','manage'),'post',
		function(\gnomephp\input\Input $input) use ($controller, $user){

			try{
				$old_password = (string)$input->post->get('old_password');


				if ($old_password){
					$password = (string)$input->post->get('password')
					->required('New password  is required for setting a new password')
					->validate('Password');
					$input->post->get('password2')->matches($password, 'New password')->validate('Confirm new password');
						
					if (!$user->validatePassword($old_password)){
						Message::add(Message::ERROR, 'Old password does not match with your current password, please try again.');
						return;
					}
						
						
					$user->setPassword($user->getUsername(), $password);
						
				}

				$email = $input->post->get('email')->email()->required()->validate('Email');
				$user->setEmail((string)$email);

					

				dbs\AuthDB::load();
				dbs\AuthDB::getEM()->persist($user);
				dbs\AuthDB::getEM()->flush();


				Message::add(Message::SUCCESS, "Your account details has been updated.");
					
					
			}catch(\gnomephp\input\DataFieldValidException $e){

				Message::add(Message::ERROR, implode('<br />', $e->getErrors()));
			}

		}

		);

		$this->view->assign('manForm', $form);

		$this->view->render('account/manage');
	}

	public function login(){
		try{
			parent::login();
		}catch(\Exception $e){
			Message::add(Message::ERROR, 'Could not login to your account. Wrong Username / Password combination.');
		}
		$form = $this->view->createForm('login', $this->view->url->linkTo('Auth','login'),'post');

		$this->view->assign('loginForm', $form);

		$this->view->render('account/login');
	}

	public function register(){
		$controller = $this;
		$captcha = $this->captcha;
		$notifier = $this->notifier;
		$form = $this->view->createForm('register', $this->view->url->linkTo('Auth','register'),'post',
		function(\gnomephp\input\Input $input) use ($controller, $captcha, $notifier){

			try{
				$username = $input->post->get('username')
				->maxLength(32)
				->required()
				->validate('Username');
				$password = $input->post->get('password')->required()->validate('Password');
				$email = $input->post->get('email')->email()->required()->validate('Email');

				if (\gnomephp\Configuration::get('site','use_captcha') && !$captcha->isVerified('captchaReg')){
					Message::add(Message::ERROR, 'Human verification was incorrect, please try again.');
					return;
				}

					
					
				$account = new \wow\modelauth\Account((string)$username, (string)$password);
				$account->setEmail((string)$email);

					
				if (\wow\modelauth\Account::canCreateUser($account)){

					// Validation link.
					$validlink = false;
					if (\gnomephp\Configuration::get('site','send_confirm_email')){
						$account->setLocked(true);
						$token = new \wow\model\AccountToken((string)$username);
						$validlink = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] ? 'https' : 'http').'://' . $_SERVER['HTTP_HOST']  . $controller->view->url->linkTo('Auth', 'validate', array('key' => $token->getHash()));
					}


					if (\gnomephp\Configuration::get('site','send_confirm_email')){
						Doctrine::getEM()->persist($token);
						Doctrine::getEM()->flush();
					}

					dbs\AuthDB::load();
					dbs\AuthDB::getEM()->persist($account);
					dbs\AuthDB::getEM()->flush();
					if (\gnomephp\Configuration::get('site','send_confirm_email')){
						Message::add(Message::WARNING, "A confirmation mail has been sent to your email ( $email ). We sent you a confirmation link, please click this to unlock your account.");
					}else{
						Message::add(Message::SUCCESS, "You are now registered on our site. You may connect to our server.");
					}
					// Send email.
					if (\gnomephp\Configuration::get('site','send_register_email') || \gnomephp\Configuration::get('site','send_confirm_email')){
						$notifier->load('AccountMails')->notifyOnEmail($email, $username, $password, $validlink);
					}



					$controller->redirect($controller->view->url->linkTo('Auth','login'));
				}else{
					Message::add(Message::ERROR, "Username already exist in our system. Please select another username.");
				}

					
					
			}catch(\gnomephp\input\DataFieldValidException $e){

				Message::add(Message::ERROR, implode('<br />', $e->getErrors()));
			}

		}

		);

		$this->view->assign('regForm', $form);
		$this->view->assign('rules', \wow\model\Page::getPage(\wow\model\Page::PAGE_ACC_REGISTER, $this->user, $this->view->getConfig('permission', 'admin_acc_rules'),
		'<ul class="menu"><li><h4>Be nice</h4></li><li><h4>Dont cheat</h4></li><li><h4>Enjoy the game</h4></li><li><h4>Oh, and admin click to edit me!</h4></li></ul>', 
		3));
		$this->view->render('account/register');
	}


	public function retrieve($key=null){
		if (\gnomephp\Configuration::get('site','enable_account_retrieval')){
			if ($key){
				if ($token = \wow\model\PasswordReset::isValid($key)){
					$user = \wow\modelauth\Account::getUserByUsername($token->getUsername());

					$pw = \wow\modelauth\Account::generateRandomPw();


					$user->setPassword($token->getUsername(), $pw);

					dbs\AuthDB::load();
					dbs\AuthDB::getEM()->persist($user);
					dbs\AuthDB::getEM()->flush();

					\wow\model\PasswordReset::unvalidate($key);


					$this->view->assign('p', $pw);
					$this->view->assign('u', $token->getUsername());


					$this->view->render('account/retrievesuccess');
				}else{
					Message::add(Message::ERROR, 'Unvalid password reset key.');
					$this->redirect($this->view->url->linkTo('Application','index'));
				}
			}else{

				$controller = $this;
				$captcha = $this->captcha;
				$notifier = $this->notifier;
				$form = $this->view->createForm('retrieve', $this->view->url->linkTo('Auth','retrieve'),'post',
				function(\gnomephp\input\Input $input) use ($controller, $captcha, $notifier){

					try{
						$username = $input->post->get('username')
						->required()
						->validate('Username');
						$email = $input->post->get('email')->email()->required()->validate('Email');

						if (\gnomephp\Configuration::get('site','use_captcha') && !$captcha->isVerified('captchaReg')){
							Message::add(Message::ERROR, 'Human verification was incorrect, please try again.');
							return;
						}

							
						$user = \wow\modelauth\Account::getUserByUsername((string)$username);
							
							
						if ($user && $user->getEmail() == ((string)$email)){
							$token = new \wow\model\PasswordReset((string)$username);

							$link = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] ?
							'https' : 'http').'://' . $_SERVER['HTTP_HOST']  . 
							$controller->view->url->linkTo('Auth', 'retrieve', array('key' => $token->getHash()));


							$notifier->load('AccountMails')->sendResetLink((string)$email, (string)$username, $link);

							Doctrine::load();
							Doctrine::getEM()->persist($token);
							Doctrine::getEM()->flush();

							Message::add(Message::SUCCESS,
						"We have sent you a email to $email with simple instructions to
						 reset your password.");
						}else{
							Message::add(Message::ERROR, 'Unfortunately this username / email does not exist in our system.');
						}



					}catch(\gnomephp\input\DataFieldValidException $e){

						Message::add(Message::ERROR, implode('<br />', $e->getErrors()));
					}

				}

				);

				$form->rememberPostValues();
				$this->view->assign('regForm', $form);

				$this->view->render('account/retrieve');
			}
		}
	}

	public function validate($key){

		if ($token = \wow\model\AccountToken::isValid($key)){
			\wow\modelauth\Account::unlockUser($token->getUsername());
			\wow\model\AccountToken::unvalidate($key);
			Message::add(Message::SUCCESS, 'Congratulations, you\'re account is successfully validated. You can now play on our servers and login to our site.');
		}else{
			Message::add(Message::ERROR, 'Unvalid validation key.');
		}
		$this->redirect($this->view->url->linkTo('Application','index'));
	}

}
